package com.mayisoftware.mayioa.business.worktime.impl.serviceImpl;

import com.mayisoftware.mayioa.business.worktime.api.common.TMWorktimeConstants;
import com.mayisoftware.mayioa.business.worktime.api.domain.*;
import com.mayisoftware.mayioa.business.worktime.api.service.ITMWorkTimeLieService;
import com.mayisoftware.mayioa.business.worktime.impl.dao.TmWorktimeMapper;
import com.mayisoftware.mayioa.common.impl.utils.DateUtils;
import com.mayisoftware.mayioa.common.impl.utils.ExcelReadWriteUtils;
import com.mayisoftware.mayioa.common.impl.utils.file.FileUtils;
import com.mayisoftware.mayioa.platform.api.domain.SysUser;
import com.mayisoftware.mayioa.platform.impl.util.ShiroUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.*;

@Service
public class TMWorkTimeLieServiceImpl implements ITMWorkTimeLieService {
    private static final Logger log = LoggerFactory.getLogger(TMWorkTimeLieServiceImpl.class);

    @Autowired
    private TmWorktimeMapper wtMapper;

    /**
     * 主检查函数入口
     * @param tmFiles：工时月结和详单文件列表
     * @return 返回结果 true：成功，false：失败
     */
    @Override
    public boolean check(List<TMWorkTimeFileInfo> tmFiles,String errorFilePath){

        boolean checkResult = false;
        for (TMWorkTimeFileInfo itemDetailFile : tmFiles) {
            FileUtils.writeLog(errorFilePath,"解析并入库文件："+itemDetailFile.getFileName());
            if (TMWorktimeConstants.TM_FILE_TYPE.MONTH==itemDetailFile.getFileType()){
                checkResult =  parseMonthlyFiles(itemDetailFile,errorFilePath);
            }else if (TMWorktimeConstants.TM_FILE_TYPE.DETAIL==itemDetailFile.getFileType()){
                checkResult = parseDetailFiles(itemDetailFile,errorFilePath);
            }

            if (checkResult==false){
                break;
            }
        }

        return checkResult;
    }

    /**
     * 处理详单文件，导入数据库
     * @param itemDetailFile：文件名称
     * @return
     */
    private boolean parseDetailFiles(TMWorkTimeFileInfo itemDetailFile,String errorFilePath){
        try{
            List<TMWrokTimeFlow> tmFLows = getTMWorktimeFlows(itemDetailFile,errorFilePath);
            if (tmFLows.size()>0){
                int existCount = wtMapper.isTmFlowsExist(tmFLows.get(0));
                if (existCount==0||existCount<=tmFLows.size()){
                    wtMapper.deleteExistTmFlows(tmFLows.get(0));
                    wtMapper.batchInsertTmFlows(tmFLows);
                }

                wtMapper.deleteDoubtRepairMonth(tmFLows.get(0));
                wtMapper.batchInsertDoubtRepairMonth();
                wtMapper.deleteDoubtRepairNight(tmFLows.get(0));
                wtMapper.batchInsertDoubtRepairNight();
            }
        }catch(Exception ex){
            FileUtils.writeLog(errorFilePath,"入库异常：请确认详单文件中的Sheet页工时流水格式是否正确："+itemDetailFile.getFileName()+":"+ex.getMessage());
            log.error(ex.getMessage());
            return false;
        }

        try {
            List<TMWorktimeGoOutFlow> gotoFlows = getTMWorktimeGooutFlows(itemDetailFile,errorFilePath);
            if (gotoFlows.size() > 0) {
                int existCount = wtMapper.isTmGooutFlowsExist(gotoFlows.get(0));
                if (existCount == 0 || existCount <= gotoFlows.size()) {
                    wtMapper.deleteExistTmGooutFlows(gotoFlows.get(0));
                    wtMapper.batchInsertTmGooutFlows(gotoFlows);
                }

            }
        }catch (Exception ex){
            FileUtils.writeLog(errorFilePath,"入库异常：请确认详单文件中的Sheet页公干流水格式是否正确："+itemDetailFile.getFileName()+":"+ex.getMessage());
            log.error(ex.getMessage());
            return false;
        }

        try {
            List<TMWorktimeExtraFlow> extraFlows = getTMWorktimeExtraFlows(itemDetailFile,errorFilePath);
            if (extraFlows.size() > 0) {
                int existCount = wtMapper.isTmExtraFlowsExist(extraFlows.get(0));
                if (existCount == 0 || existCount <= extraFlows.size()) {
                    wtMapper.deleteExistTmExtraFlows(extraFlows.get(0));
                    wtMapper.batchInsertTmExtraFlows(extraFlows);
                }
            }
        }catch(Exception ex){
            FileUtils.writeLog(errorFilePath,"入库异常：请确认详单文件中的Sheet页加班流水格式是否正确："+itemDetailFile.getFileName()+":"+ex.getMessage());
            log.error(ex.getMessage());
            return false;
        }

        try {
            List<TMWorktimeLeaveFlow> leaveFlows = getTMWorktimeLeaveFlows(itemDetailFile,errorFilePath);
            if (leaveFlows.size() > 0) {
                int existCount = wtMapper.isTmLeaveFlowsExist(leaveFlows.get(0));
                if (existCount == 0 || existCount <= leaveFlows.size()) {
                    wtMapper.deleteExistTmLeaveFlows(leaveFlows.get(0));
                    wtMapper.batchInsertTmLeaveFlows(leaveFlows);
                }

            }
        }catch (Exception ex){
            FileUtils.writeLog(errorFilePath,"入库异常：请确认详单文件中的Sheet页请假流水格式是否正确："+itemDetailFile.getFileName()+":"+ex.getMessage());
            log.error(ex.getMessage());
            return false;
        }
        try {
            List<TMWorktimeDetailFlow> detailFlows = getTMWorktimeDetailFlows(itemDetailFile,errorFilePath);
            if (detailFlows.size() > 0) {
                int existCount = wtMapper.isTmDetailFlowsExist(detailFlows.get(0));
                if (existCount == 0 || existCount <= detailFlows.size()) {
                    wtMapper.deleteExistTmDetailFlows(detailFlows.get(0));
                    wtMapper.batchInsertTmDetailFlows(detailFlows);
                }

            }
        }catch(Exception ex){
            FileUtils.writeLog(errorFilePath,"入库异常：请确认详单文件中的Sheet页日工时汇总明细格式是否正确："+itemDetailFile.getFileName()+":"+ex.getMessage());
            log.error(ex.getMessage());
            return false;
        }

        return  true;
    }



    private List<TMWorktimeDetailFlow> getTMWorktimeDetailFlows(TMWorkTimeFileInfo tmFile,String errorFilePath){
        List<TMWorktimeDetailFlow> retList = new ArrayList<>();
        File detailFile = new File(tmFile.getFileName());
        List<String> contents =null;
        try {
            contents= ExcelReadWriteUtils.readExcelList(detailFile.getAbsolutePath(),5);
        } catch (InvalidFormatException e) {
            FileUtils.writeLog(errorFilePath,"文件格式异常，请确认："+e.getMessage());
            e.printStackTrace();
            return retList;
        } catch (IOException e) {
            FileUtils.writeLog(errorFilePath,"IO异常，请确认文件是否已经打开："+e.getMessage());
            e.printStackTrace();
            return retList;
        }

        int count = 0;
        for (String item: contents) {
            count++;
            if (count == 1) {
                continue;
            }

            String tmp = item.replace(",","");
            if (tmp.trim().isEmpty()){
                continue;
            }

            List<String> items = Arrays.asList(item.split(",",-1));
            TMWorktimeDetailFlow detailFlow = new TMWorktimeDetailFlow();
            detailFlow.setId(items.get(0));
            detailFlow.setHwCode(items.get(1));
            detailFlow.setName(items.get(2));
            detailFlow.setCheckDate(items.get(3));
            detailFlow.setType(items.get(4));
            detailFlow.setMode(items.get(5));
            detailFlow.setOffShore(items.get(7));
            detailFlow.setPo(items.get(9));
            detailFlow.setHwLevel(items.get(10));
            detailFlow.setLevelType(items.get(11));
            detailFlow.setStatus(items.get(13));
            detailFlow.setAtWorkHours(convertToFloat(items.get(14)));
            detailFlow.setLeaveHours(convertToFloat(items.get(15)));
            detailFlow.setAbsenceHours(convertToFloat(items.get(16)));
            detailFlow.setPunishHours(convertToFloat(items.get(17)));
//            detailFlow.setWaxAndWanHours(convertToFloat(items.get(18)));
            detailFlow.setExtraHours(convertToFloat(items.get(19)));
            detailFlow.setHwPM(items.get(21));

            detailFlow.setMonth(tmFile.getMonth());
            detailFlow.setRegion(tmFile.getRegion());
            detailFlow.setBg(tmFile.getBg());
            detailFlow.setBu(tmFile.getBu());
            detailFlow.setPdu(tmFile.getPdu());
            detailFlow.setPoNum(tmFile.getPoNum());
            detailFlow.setFileName(tmFile.getFileName());
            detailFlow.setFileType(tmFile.getFileType().toString());
//            detailFlow.setUpdateUser(user.getUserId()+"");
            retList.add(detailFlow);
        }

        return retList;
    }

    private List<TMWorktimeLeaveFlow> getTMWorktimeLeaveFlows(TMWorkTimeFileInfo tmFile,String errorFilePath){
        List<TMWorktimeLeaveFlow> retList = new ArrayList<>();
        File detailFile = new File(tmFile.getFileName());
        List<String> contents =null;
        try {
            contents= ExcelReadWriteUtils.readExcelList(detailFile.getAbsolutePath(),4);
        } catch (InvalidFormatException e) {
            FileUtils.writeLog(errorFilePath,"文件格式异常，请确认："+e.getMessage());
            e.printStackTrace();
            return retList;
        } catch (IOException e) {
            FileUtils.writeLog(errorFilePath,"IO异常，请确认文件是否已经打开："+e.getMessage());
            e.printStackTrace();
            return retList;
        }


        int count = 0;
        for (String item: contents) {
            count++;
            if (count == 1) {
                continue;
            }

            String tmp = item.replace(",","");
            if (tmp.trim().isEmpty()){
                continue;
            }

            List<String> items = Arrays.asList(item.split(",",-1));
            TMWorktimeLeaveFlow leaveFlow = new TMWorktimeLeaveFlow();
            leaveFlow.setId(items.get(0));
            leaveFlow.setHwCode(items.get(1));
            leaveFlow.setName(items.get(2));
            leaveFlow.setLeaveDate(items.get(3));
            leaveFlow.setLeaveStartTime(items.get(4));
            leaveFlow.setLeaveEndTime(items.get(5));
            leaveFlow.setLeaveDays(convertToFloat(items.get(6)));
            leaveFlow.setLeaveFlowNo(items.get(7));

            leaveFlow.setMonth(tmFile.getMonth());
            leaveFlow.setRegion(tmFile.getRegion());
            leaveFlow.setBg(tmFile.getBg());
            leaveFlow.setBu(tmFile.getBu());
            leaveFlow.setPdu(tmFile.getPdu());
            leaveFlow.setPoNum(tmFile.getPoNum());
            leaveFlow.setFileName(tmFile.getFileName());
            leaveFlow.setFileType(tmFile.getFileType().toString());
//            leaveFlow.setUpdateUser(user.getUserId()+"");
            retList.add(leaveFlow);
        }

        return retList;
    }

    private List<TMWorktimeExtraFlow> getTMWorktimeExtraFlows(TMWorkTimeFileInfo tmFile,String errorFilePath){
        List<TMWorktimeExtraFlow> retList = new ArrayList<>();
        File detailFile = new File(tmFile.getFileName());
        List<String> contents =null;
        try {
            contents= ExcelReadWriteUtils.readExcelList(detailFile.getAbsolutePath(),3);
        } catch (InvalidFormatException e) {
            FileUtils.writeLog(errorFilePath,"文件格式异常，请确认："+e.getMessage());
            e.printStackTrace();
            return retList;
        } catch (IOException e) {
            FileUtils.writeLog(errorFilePath,"IO异常，请确认文件是否已经打开："+e.getMessage());
            e.printStackTrace();
            return retList;
        }

        int count = 0;
        for (String item: contents) {
            count++;
            if (count == 1) {
                continue;
            }

            String tmp = item.replace(",","");
            if (tmp.trim().isEmpty()){
                continue;
            }

            List<String> items = Arrays.asList(item.split(",",-1));
            TMWorktimeExtraFlow extraFlow = new TMWorktimeExtraFlow();
            extraFlow.setId(items.get(0));
            extraFlow.setHwCode(items.get(1));
            extraFlow.setName(items.get(2));
            extraFlow.setWorkDate(items.get(3));
            extraFlow.setApplyStartTime(items.get(4));
            extraFlow.setApplyEndTime(items.get(5));
            extraFlow.setRealStartTime(items.get(6));
            extraFlow.setRealEndTime(items.get(7));
            extraFlow.setExtraDays(convertToFloat(items.get(8)));
            extraFlow.setExtraNo(items.get(9));

            extraFlow.setMonth(tmFile.getMonth());
            extraFlow.setRegion(tmFile.getRegion());
            extraFlow.setBg(tmFile.getBg());
            extraFlow.setBu(tmFile.getBu());
            extraFlow.setPdu(tmFile.getPdu());
            extraFlow.setPoNum(tmFile.getPoNum());
            extraFlow.setFileName(tmFile.getFileName());
            extraFlow.setFileType(tmFile.getFileType().toString());
//            extraFlow.setUpdateUser(user.getUserId()+"");
            retList.add(extraFlow);
        }

        return retList;
    }

    private List<TMWorktimeGoOutFlow> getTMWorktimeGooutFlows(TMWorkTimeFileInfo tmFile,String errorFilePath){
        List<TMWorktimeGoOutFlow> retList = new ArrayList<>();
        File detailFile = new File(tmFile.getFileName());
        List<String> contents =null;
        try {
            contents= ExcelReadWriteUtils.readExcelList(detailFile.getAbsolutePath(),2);
        } catch (InvalidFormatException e) {
            FileUtils.writeLog(errorFilePath,"文件格式异常，请确认："+e.getMessage());
            e.printStackTrace();
            return retList;
        } catch (IOException e) {
            FileUtils.writeLog(errorFilePath,"IO异常，请确认文件是否已经打开："+e.getMessage());
            e.printStackTrace();
            return retList;
        }

        int count = 0;
        for (String item: contents) {
            count++;
            if (count == 1) {
                continue;
            }

            String tmp = item.replace(",","");
            if (tmp.trim().isEmpty()){
                continue;
            }

            List<String> items = Arrays.asList(item.split(",",-1));
            TMWorktimeGoOutFlow gooutFlow = new TMWorktimeGoOutFlow();
            gooutFlow.setId(items.get(0));
            gooutFlow.setHwCode(items.get(1));
            gooutFlow.setName(items.get(2));
            gooutFlow.setGooutDate(items.get(3));
            gooutFlow.setGooutStartTime(items.get(4));
            gooutFlow.setGooutEndTime(items.get(5));
            gooutFlow.setGooutDays(items.get(6));
            gooutFlow.setGooutFlowNo(items.get(7));

            gooutFlow.setMonth(tmFile.getMonth());
            gooutFlow.setRegion(tmFile.getRegion());
            gooutFlow.setBg(tmFile.getBg());
            gooutFlow.setBu(tmFile.getBu());
            gooutFlow.setPdu(tmFile.getPdu());
            gooutFlow.setPoNum(tmFile.getPoNum());
            gooutFlow.setFileName(tmFile.getFileName());
            gooutFlow.setFileType(tmFile.getFileType().toString());
//            gooutFlow.setUpdateUser(user.getUserId()+"");
            retList.add(gooutFlow);
        }

        return retList;
    }

    private List<TMWrokTimeFlow> getTMWorktimeFlows(TMWorkTimeFileInfo tmFile,String errorFilePath){
        List<TMWrokTimeFlow> retList = new ArrayList<>();
        File detailFile = new File(tmFile.getFileName());
        List<String> contents =null;
        try {
            contents= ExcelReadWriteUtils.readExcelList(detailFile.getAbsolutePath(),1);
        } catch (InvalidFormatException e) {
            FileUtils.writeLog(errorFilePath,"文件格式异常，请确认："+e.getMessage());
            e.printStackTrace();
            return retList;
        } catch (IOException e) {
            FileUtils.writeLog(errorFilePath,"IO异常，请确认文件是否已经打开："+e.getMessage());
            e.printStackTrace();
            return retList;
        }

        int count = 0;
        for (String item: contents) {
            count++;
            if (count == 1) {
                continue;
            }

            String tmp = item.replace(",","");
            if (tmp.trim().isEmpty()){
                continue;
            }

            List<String> items = Arrays.asList(item.split(",",-1));
            TMWrokTimeFlow tmFlow = new TMWrokTimeFlow();
            tmFlow.setId(items.get(0));
            tmFlow.setHwCode(items.get(1));
            tmFlow.setName(items.get(2));
            tmFlow.setTerminalId(items.get(3));
            tmFlow.setTerminalName(items.get(4));
            tmFlow.setMode(items.get(5));
            tmFlow.setOffshore(items.get(6));
            tmFlow.setOwnHost(items.get(7));
            tmFlow.setSigninDate(items.get(8));
            tmFlow.setSigninTime(items.get(9));
            tmFlow.setIsRepair(items.get(11));
            tmFlow.setRepairFlowNo(items.get(12));

            tmFlow.setMonth(tmFile.getMonth());
            tmFlow.setRegion(tmFile.getRegion());
            tmFlow.setBg(tmFile.getBg());
            tmFlow.setBu(tmFile.getBu());
            tmFlow.setPdu(tmFile.getPdu());
            tmFlow.setPoNum(tmFile.getPoNum());
            tmFlow.setFileName(tmFile.getFileName());
            tmFlow.setFileType(tmFile.getFileType().toString());
//            tmFlow.setUpdateUser(user.getUserId()+"");
            retList.add(tmFlow);
        }

        return retList;
    }


    private boolean parseMonthlyFiles(TMWorkTimeFileInfo itemDetailFile,String errorFilePath){
        List<TMWorktimeMonthInfo> monthInfos = getMonthlyDatas(itemDetailFile,errorFilePath);
        try {
            if (monthInfos.size() > 0) {
                int existCount = wtMapper.isTmMonthExist(monthInfos.get(0));
                //数据量大于等于已有数据量才执行替换操作
                if (existCount == 0 || existCount <= monthInfos.size()) {
                    wtMapper.deleteExistTmMonth(monthInfos.get(0));
                    wtMapper.batchInsertTmMonths(monthInfos);
                    return true;
                }
            }
        }catch (Exception ex){
            FileUtils.writeLog(errorFilePath,"入库异常，请确认："+ex.getMessage());
            log.error(ex.getMessage());
            return false;
        }
        return false;
    }

    private List<TMWorktimeMonthInfo> getMonthlyDatas(TMWorkTimeFileInfo tmFile,String errorFilePath){
        List<TMWorktimeMonthInfo> retList = new ArrayList<>();
        File detailFile = new File(tmFile.getFileName());
        List<String> contents = null;
        try {
            contents= ExcelReadWriteUtils.readExcelList(detailFile.getAbsolutePath(),1);
        } catch (InvalidFormatException e) {
            FileUtils.writeLog(errorFilePath,"文件格式异常，请确认："+e.getMessage());
            e.printStackTrace();
            return retList;
        } catch (IOException e) {
            FileUtils.writeLog(errorFilePath,"IO异常，请确认文件是否已经打开："+e.getMessage());
            e.printStackTrace();
            return retList;
        }

        int count = 0;
        boolean firstFormat = false;
        for (String item: contents) {
            count++;
            if (count == 1) {
                continue;
            }else if(count==2){
                String title = "实际打卡工时(单位:人时)";
                if (item.contains(title)){
                    firstFormat = true;
                }
                continue;
            }

            if (count<=4){
                continue;
            }

            //跳过空行
            String tmp = item.replace(",","");
            if (tmp.trim().isEmpty()){
                continue;
            }

            List<String> items = Arrays.asList(item.split(",",-1));
            TMWorktimeMonthInfo monthInfo = new TMWorktimeMonthInfo();
            monthInfo.setPo(items.get(0));
            monthInfo.setName(items.get(1));
            monthInfo.setId(items.get(2));
            monthInfo.setHwLevel(items.get(3));
            monthInfo.setIsFreshStudent(items.get(4));
            if (firstFormat) {
                monthInfo.setNeedServiceHours(getHours(items.get(5)));
                monthInfo.setMinServiceHours(getHours(items.get(7)));
                monthInfo.setLateHours(getHours(items.get(6)));
                monthInfo.setActualServiceHours(getHours(items.get(8)));
                monthInfo.setOweServiceHours(getHours(items.get(9)));
                monthInfo.setExtraHours(getHours(items.get(10)));
                monthInfo.setIsOffShore(items.get(11));
                monthInfo.setTotalPayDays(sumTotalPayDays(items.get(12),items.get(13)));
                monthInfo.setHwPm(items.get(14));

            }else{
                monthInfo.setNeedServiceHours(getDays(items.get(5)));
                monthInfo.setLateHours(getDays(items.get(6)));
                monthInfo.setAbsenceHours(getDays(items.get(7)));
                monthInfo.setLateHours(getDays(items.get(8)));
                monthInfo.setEarlyHours(getDays(items.get(9)));
                monthInfo.setGoOutHours(getDays(items.get(10)));
                monthInfo.setRepairTimes(items.get(11));
                monthInfo.setMinServiceHours(getDays(items.get(12)));
                monthInfo.setActualServiceHours(getDays(items.get(13)));
                monthInfo.setOweServiceHours(getDays(items.get(14)));
                monthInfo.setExtraHours(getDays(items.get(15)));
                monthInfo.setIsOffShore(items.get(16));
                monthInfo.setTotalPayDays(getDays(items.get(17)));
                monthInfo.setHwPm(items.get(19));
            }

            monthInfo.setMonth(tmFile.getMonth());
            monthInfo.setRegion(tmFile.getRegion());
            monthInfo.setBg(tmFile.getBg());
            monthInfo.setBu(tmFile.getBu());
            monthInfo.setPdu(tmFile.getPdu());
            monthInfo.setPoNum(tmFile.getPoNum());
            monthInfo.setFileName(tmFile.getFileName());
            monthInfo.setFileType(tmFile.getFileType().toString());
            monthInfo.setUpdateBy(tmFile.getCreateBy());
            retList.add(monthInfo);
        }

        return retList;
    }

    private double sumTotalPayDays(String val1,String val2){
        double d = 0.0;
        if (val1==null&&val2==null){
            return d;
        }
        if (val1==null){
            return  getDays(val2);
        }
        if (val2==null){
            return  getDays(val1);
        }
        d =getDays(val1)+getDays(val2);
        return d;
    }

    private double getHours(String val){
        double d = 0.0;
        if (val==null){
            return d;
        }
        try {
            d = Double.parseDouble(val) * 8;
        }catch (Exception ex){
            log.error(ex.getMessage());
        }

        return d;
    }

    private double getDays(String val){
        double d = 0.0;
        if (val==null){
            return d;
        }
        try {
            d = Double.parseDouble(val) ;
        }catch (Exception ex){
            log.error(ex.getMessage());
        }

        return d;
    }

    private float convertToFloat(String str){
        if (str==null ||str.trim().isEmpty()){
            return 0;
        }
        float ret = 0;
        try {
            ret = Float.parseFloat(str);
        }catch (Exception ex){
            System.out.println(ex.getMessage());
        }
        return ret;
    }
}
